<?php
require_once ("Kzend/Controller/Action/Abstract.php");

/**
 * Controller base
 */
abstract class ControllerBase extends Kzend_Controller_Action_Abstract {
	
	/**
	 * Configuration
	 *
	 * @var mixed
	 * @access protected
	 */
	protected $_configs;
	
	/**
	 * Module name
	 *
	 * @var string
	 * @access protected
	 */
	protected $_module = '';
	
	/**
	 * Controller name
	 *
	 * @var string
	 * @access private
	 */
	protected $_controller = '';
	
	/**
	 * Action Name
	 *
	 * @var string
	 * @access protected
	 */
	protected $_action = '';
	
	/**
	 * Plug-in
	 *
	 * @var mixed
	 * @access protected
	 */
	protected $_plugins = null;
	
	/**
	 * Error Message
	 *
	 * @var array
	 * @access protected
	 */
	protected $_errors = array ();
	public function init() {
		parent::init ();
		
		// Get Module, Controller, Action name
		$this->_module = $this->_request->getModuleName ();
		$this->_controller = $this->_request->getControllerName ();
		$this->_action = $this->_request->getActionName ();
		
		// Get front controller, configs, plugins
		$front = $this->getFrontController ();
		$this->_configs = $front->getParam ( 'config' );
		$this->_plugins = $front->getPlugins ();
		
		$this->_initView ();
		
		// Assign controller name to view
		$this->view->controller = $this->_controller;
		$this->view->action = $this->_action;
	}
	
	/**
	 * Init wiew
	 *
	 * @return ControllerBase
	 */
	private function _initView() {
		// Get template engine
		if ($this->view instanceof Zend_View) {
			parent::initView ();
		}
		return $this;
	}
	
	/**
	 * View assign
	 *
	 * @param mixed $name        	
	 * @param mixed $param        	
	 * @return ControllerBase
	 */
	public function assign($name, $param) {
		$this->view->assign ( $name, $param );
		return $this;
	}
	
	/**
	 * Pass error messages to template
	 *
	 * @param string/array $errMsg        	
	 * @return ControllerBase
	 */
	public function setError($errMsg) {
		return $this->_setError ( $errMsg );
	}
	
	/**
	 * Pass error messages to template
	 *
	 * @param string/array $errMsg        	
	 * @return ControllerBase
	 */
	protected function _setError($errMsg) {
		if (is_array ( $errMsg )) {
			$this->_errors = array_merge ( $this->_errors, $errMsg );
		} else {
			$this->_errors [] = $errMsg;
		}
		$this->_setParam ( 'errors', $this->_errors );
		return $this;
	}
	
	/**
	 * Get form params
	 *
	 * @param array $names        	
	 * @param array $namespace        	
	 * @access protected
	 * @return mixed
	 */
	protected function _getFormParams(array $names, $namespace) {
		// If request is back from other page(e.g. confirm page to index page),
		// set session value to form
		if ($this->_request->getPost ( 'back' ) === null) {
			$params = $this->_mergeValue ( $names, $namespace );
		} else {
			$session = new Zend_Session_Namespace ( $namespace );
			$params = $session->params;
		}
		
		return $params;
	}
	
	/**
	 * Merge session value and post value
	 *
	 * @param array $names
	 *        	Value to merge
	 * @param mixed $namespace
	 *        	Session namespace
	 * @access protected
	 * @return array Merged value
	 */
	protected function _mergeValue(array $names, $namespace) {
		$session = new Zend_Session_Namespace ( $namespace );
		$params = array ();
		foreach ( $names as $key => $val ) {
			$params [$val] = $this->_request->getPost ( $val );
		}
		
		if (isset ( $session->params )) {
			$params = array_merge ( $session->params, $params );
		}
		
		return $params;
	}
	
	/**
	 * Set default value
	 *
	 * @param array $params
	 *        	Form elements as value
	 * @access protected
	 * @return Kmgokan_Controller_Action
	 */
	protected function _setDefaultValues(array $params) {
		foreach ( $params as $key => $val ) {
			$this->assign ( $key, $val );
		}
		
		return $this;
	}
	
	/**
	 * Get plugin object
	 *
	 * @param string $class
	 *        	Plugin's class name
	 * @access protected
	 * @return Plugin object
	 */
	protected function _getPlugin($class) {
		if (! is_array ( $this->_plugins )) {
			return null;
		}
		
		foreach ( $this->_plugins as $plugin ) {
			if ($class === get_class ( $plugin )) {
				return $plugin;
			}
		}
		
		return null;
	}
	protected function _go($action, $controller = null, $module = null, $params = null) {
		if ($this->_request->isXmlHttpRequest ()) {
			return;
		}
		parent::_forward ( $action, $controller, $module, $params );
		return;
	}
	
	/**
	 * Show the specified message.
	 *
	 * @param string $message        	
	 * @param string $href        	
	 */
	protected function _showMessage($message, $href = null) {
		parent::_forward ( 'index', 'message', $this->_module, array (
				'message' => $message,
				'href' => $href 
		) );
		return;
	}
	public function preDispatch() {
		parent::preDispatch ();
		
		$configs = Zend_Registry::get ( "appConfig" );
		if (isset ( $configs ['kzend'] ['viewAssign'] )) {
			$viewAssign = $configs ['kzend'] ['viewAssign'];
			foreach ( $viewAssign as $key => $var ) {
				$this->view->assign ( $key, $var );
			}
		}
	}
	public function postDispatch() {
		parent::postDispatch ();
		// If error occurred, assign to template.
		if (is_array ( $this->_getParam ( 'errors' ) ) && count ( $this->_getParam ( 'errors' ) ) > 0) {
			$this->assign ( 'errors', $this->_getParam ( 'errors' ) );
		}
		// If request has 'message', assign to template.
		$message = $this->_getParam ( 'message' );
		if (isset ( $message ) && ! is_null ( $message )) {
			$this->assign ( 'message', $message );
		}
	}
	
	/**
	 * Output log at end action
	 *
	 * @param string $message        	
	 * @param string $sid        	
	 * @param string $type        	
	 */
	protected function _outLogEndAction($message = null, $sid = null, $type = 'info') {
		$logger = $this->getLogger ();
		$sid = isset ( $sid ) ? 'SUBSCRIBER_ID->' . substr ( $sid, 0, 12 ) . '; ' : '';
		// $setMassage = $message . '; ' . $sid . 'LOGIN_USER->' .
		// $_SESSION['Zend_Auth']['storage'] . '; ' . 'CONTROLLER_NAME->' .
		// $this->_controller . '; ' . 'ACTION_NAME->' . $this->_action;
		$setMassage = $message . '; ' . $sid . 'CONTROLLER_NAME->' . $this->_controller . '; ' . 'ACTION_NAME->' . $this->_action;
		
		switch ($type) {
			case 'info' :
				$logger->info ( $setMassage );
				break;
			case 'warn' :
				$logger->warn ( $setMassage );
				break;
			case 'err' :
				$logger->err ( $setMassage );
				break;
		}
	}
	
	/**
	 * Replace content
	 *
	 * @param string $contents        	
	 * @param array $list        	
	 * @param string $conChar        	
	 * @return string
	 */
	protected function _replaceContents($contents, $list = array(), $conChar = '##') {
		foreach ( $list as $key => $value ) {
			$contents = mb_ereg_replace ( $conChar . $key . $conChar, $value, $contents );
		}
		return $contents;
	}
	
	/**
	 * Replace message content get from message.ini
	 *
	 * @param string $code        	
	 * @param array $list        	
	 * @param string $conChar        	
	 * @return string
	 */
	protected function _messageReplace($code, $list = array(), $conChar = '%') {
		$contents = $this->getMessage ( $code );
		$message = $this->_replaceContents ( $contents, $list, $conChar );
		return $message;
	}
	
	/**
	 * Make TSV data
	 *
	 * @param array $rows        	
	 * @param string $charCode        	
	 * @param string $delimiter        	
	 * @param boolean $showItemName        	
	 * @return string
	 */
	protected function makeTsvStrings($rows, $charCode = 'UTF-8', $delimiter = "\t", $showItemName = false) {
		if ($showItemName) {
			$itemList = array_keys ( ( array ) $rows [0] );
			array_unshift ( $rows, $itemList );
		}
		$str = '';
		foreach ( $rows as $key => $row ) {
			foreach ( $row as $key2 => $value ) {
				$value = str_replace ( '"', '""', $value );
				
				$str .= "\"" . $value . "\"" . $delimiter;
			}
			$str = rtrim ( $str, $delimiter );
			$str .= "\r\n";
		}
		$str = rtrim ( $str, "\r\n" );
		return mb_convert_encoding ( $str, $charCode );
	}
	
	/**
	 * TSV output
	 *
	 * @param string $str        	
	 * @param string $filename        	
	 */
	protected function outputTsvFile($str, $filename) {
		Zend_Layout::resetMvcInstance ();
		$this->_helper->viewRenderer->setNoRender ();
		
		header ( "Cache-Control: public" );
		header ( "Pragma: public" );
		header ( "Content-type: text/tab-separated-values" );
		header ( "Content-Disposition: attachment; filename=" . $filename );
		
		echo $str;
	}
	
	/**
	 * Make CSV data
	 *
	 * @param array $rows        	
	 * @param string $charCode        	
	 * @param string $delimiter        	
	 * @param boolean $showItemName        	
	 * @return string
	 */
	protected function makeCsvStrings($rows, $charCode = 'UTF-8', $delimiter = ',', $showItemName = false) {
		if ($showItemName) {
			$itemList = array_keys ( ( array ) $rows [0] );
			array_unshift ( $rows, $itemList );
		}
		$str = '';
		foreach ( $rows as $key => $row ) {
			foreach ( $row as $key2 => $value ) {
				$value = str_replace ( '"', '""', $value );
				$str .= "\"" . $value . "\"" . $delimiter;
			}
			$str = rtrim ( $str, $delimiter );
			$str .= "\r\n";
		}
		$str = rtrim ( $str, "\r\n" );
		return mb_convert_encoding ( $str, $charCode );
	}
	
	/**
	 * CSV output
	 *
	 * @param string $str        	
	 * @param string $filename        	
	 */
	protected function outputCsvFile($str, $filename) {
		Zend_Layout::resetMvcInstance ();
		$this->_helper->viewRenderer->setNoRender ();
		
		header ( "Cache-Control: public" );
		header ( "Pragma: public" );
		header ( "Content-type: text/comma-separated-values" );
		header ( "Content-Disposition: attachment; filename=" . $filename );
		
		echo $str;
	}
}
